<?php
namespace app\app\controller\v1;
use think\Db;
use think\Request;
use app\app\util\OnlineUtils;
use app\app\util\IntUtils;
use app\app\util\ShareUtils;
require_once(dirname(dirname(dirname(__FILE__))).'/util/php/wxBizDataCrypt.php');
use php\WXBizDataCrypt\WXBizDataCrypt;
class AppController extends BaseController{

	/**
	 * [wxlogin description]
	 * @param string code
	 * @return [type] [description]
	 */
	public function login(Request $request)
	{
		$header = $request->header();
		if($header['token'] && $header['token'] !=''){
			if(OnlineUtils::requestIsLogin()){
				$user_id = OnlineUtils::getUserIdBySid();
				$user = Db::name('user')->field('id,open_id,nickname,avatar_url,gender')->where('id','eq',$user_id)->find();
				return ft(200,'success',['token'=>$header['token'],'data'=>$user]);
			}else{
				return ft(500,'请重新登录');
			}
		}else{
			//第一次进入应用
			/**
			 * 3.小程序调用server获取token接口, 传入code, rawData, signature, encryptData.
			 */
			// $param = $request->param();
			$code = input("post.code");
			$rawData = input("post.rawData");
			$signature = input("post.signature");
			$encryptedData = input("post.encryptedData");
			$iv = input("post.iv");
			/**
			 * 4.server调用微信提供的jsoncode2session接口获取openid, session_key, 调用失败应给予客户端反馈
			 * , 微信侧返回错误则可判断为恶意请求, 可以不返回. 微信文档链接
			 * 这是一个 HTTP 接口，开发者服务器使用登录凭证 code 获取 session_key 和 openid。其中 session_key 是对用户数据进行加密签名的密钥。
			 * 为了自身应用安全，session_key 不应该在网络上传输。
			 * 接口地址："https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code"
			 */
			$params = [
				'appid' => CONFIG('APPID'),
				'secret' => CONFIG('SECRET'),
				'js_code' => $code,
				'grant_type' => 'authorization_code'
			];
			$url = "https://api.weixin.qq.com/sns/jscode2session";
			$res = makeRequest($url, $params);
			//result是否存在
			$reqData = json_decode($res);
			// return ft(200,'success',$reqData);
			if (!isset($reqData->session_key)) {
				return ft('202','未知错误2');
			}
			$sessionKey = $reqData->session_key;

			/**
			 * 5.server计算signature, 并与小程序传入的signature比较, 校验signature的合法性, 不匹配则返回signature不匹配的错误. 不匹配的场景可判断为恶意请求, 可以不返回.
			 * 通过调用接口（如 wx.getUserInfo）获取敏感数据时，接口会同时返回 rawData、signature，其中 signature = sha1( rawData + session_key )
			 *
			 * 将 signature、rawData、以及用户登录态发送给开发者服务器，开发者在数据库中找到该用户对应的 session-key
			 * ，使用相同的算法计算出签名 signature2 ，比对 signature 与 signature2 即可校验数据的可信度。
			 */
			$signature2 = sha1($rawData . $sessionKey);

			if ($signature2 != $signature) return ft('202','签名错误');

			/**
			 *
			 * 6.使用第4步返回的session_key解密encryptData, 将解得的信息与rawData中信息进行比较, 需要完全匹配,
			 * 解得的信息中也包括openid, 也需要与第4步返回的openid匹配. 解密失败或不匹配应该返回客户相应错误.
			 * （使用官方提供的方法即可）
			 */
			$pc = new WXBizDataCrypt(config('APPID'), $sessionKey);
			$errCode = $pc->decryptData($encryptedData, $iv, $data );

			if ($errCode !== 0) {
				return ft('202','验证失败');
			}
			$data = json_decode($data);
			//验证通过
			// $unionid = $data['unionid'];
			$openid = $data->openId;
			//获取登录状态，生成登录码
			$encode_code = base64_encode($openid);
			$access_key  = randomFromDev(100,$encode_code);
			//查询用户是否存在
			$user = Db::name('user')->field('id,open_id,nickname,avatar_url,gender')->where('open_id','eq',$openid)->where('status','eq',1)->find();
			if($user){
				$token = md5(time().$user['id']);
				OnlineUtils::sidLogin($token,$user);
				return ft(200,'success',['token'=>$token,'data'=>$user]); 
			}else{
				// 注册加登录
				$arr = array('open_id'=>$openid,'nickname'=>$data->nickName,'avatar_url'=>$data->avatarUrl,'gender'=>$data->gender,'province'=>$data->province,'city'=>$data->city,'country'=>$data->country);
				//注册时间
                $arr['created_at'] = time();
				$id   = Db::name('user')->insertGetId($arr);
				$user = Db::name('user')->field('id,open_id,nickname,avatar_url,gender')->where('id','eq',$id)->find();
				//积分存入redis
				IntUtils::foundUserInt($id);
				//贡献值存入redis
                ShareUtils::foundUserCont($id);
				//把所有的球星卡都存入表
				for($i = 1;$i<16;$i++){
					Db::name('my_card')->insert(array('user_id'=>$id,'card_id'=>$i));
				}
                //把所有的道具都存入表
                for($a = 1;$a<33;$a++){
                    Db::name('my_prop')->insert(array('user_id'=>$id,'prop_id'=>$a));
                }
				//登录
				$token = md5(time().$id);
				OnlineUtils::login($token,$user);
				return ft(200,'success',['token'=>$token,'data'=>$user]);
			}	
		}
	}

	/**
	 * [wxCheck 微信验证]
	 * @return [type] [description]
	 */
	public function wxCheck()
	{
    	$signature =  input("get.signature");
        $timestamp =  input("get.timestamp");
    	$nonce     =  input('get.nonce');
    	$token     =  config('WX_TOKEN');
    	$echostr   =  input('get.echostr');
    	$arr       = array($timestamp,$nonce,$token);
    	sort($arr,SORT_STRING);
		$tmpStr    = implode($arr );
		$tmpStr    = sha1( $tmpStr );
		//验证
		if( $signature == $tmpStr ){
			header('content-type:text');
			echo $echostr;
		}else{
			return false;
		}		
	}	
	
	public function test()
	{
		$user_id = input('post.id');
		// $arr = array('open_id'=>input('open_id'),'nickname'=>input('nickname'),'avatar_url'=>input('img'),'gender'=>input('gender'));
		//注册时间
	    // $arr['created_at'] = time();
		// $id   = Db::name('user')->insertGetId($arr);
		// $user = Db::name('user')->field('id,open_id,nickname,avatar_url,gender')->where('id','eq',$id)->find();
		//积分存入redis
		// IntUtils::foundUserInt($id);
		//把所有的球星卡都存入表
		// for($i = 1;$i<16;$i++){
		// 	$arr = array('user_id'=>$id,'card_id'=>$i);
		// 	Db::name('my_card')->insert($arr);
		// }
	    //把所有的道具都存入表
	    // for($a = 1;$a<33;$a++){
	    // 	$arr = array('user_id'=>$id,'prop_id'=>$a);
	    //     Db::name('my_prop')->insert($arr);
	    // }
		$token = md5(time().$user_id);
		$user  = Db::name('user')->where('id','eq',$user_id)->find();
		// $data = Db::name('star_card_collect')->where('uid','eq',$user_id)->select();
		// $ex   = Db::name('exchange')->where('uid','eq',$user_id)->find();
		OnlineUtils::sidLogin($token,$user);
        return ft(200,'success',['token'=>$token,'data'=>$user]);
	}

	 public function socket()
		{
			$appid = '77494ad321405fb340e2d1a664850954'; //填写socket端的appid
			$appkey = '****************************'; //填写socket端的sercret
			$apiUrl = '*******************';//发送接口
			$sid=$_GET["sid"];
			$data = $_GET["data"]; //要发送的消息
			$signature = md5($appid.$sid.$data.$appkey);
			$url = $apiUrl.'?appid='.$appid.'&sid='.$sid.'&data='.$data.'&signature='.$signature;
	//        $html=file_get_contents($url);
			return ft(200,'success',$url);
	    } 
  
}